Momento TopicsでWebSocketを実現するサンプルを試してみた

Momento TopicsでWebSocketを実現するサンプルを試してみた

Momento TopicsのサンプルアプリでWebSocketを試してみました。Momento APIキーから一時的なトークンを生成する話も書いてます。
Clock Icon2024.09.28

はじめに

今回はMomentoの中のサービスの1つである、Momento TopicsをWebSocketとして使ってみます。先日開催されたServerless Days 2024に参加して、Momentoの話を聞いて調べたところ、以下の記事を見つけました。何と、以下の数行でWebSocketが実現できると書かれています。まじかよ!

https://www.gomomento.com/blog/why-are-websockets-so-hard/

// Subscribe
await topicClient.subscribe('websocket', 'mychannel', {
  onItem: (data) => { handleItem(data.valueString()); },
  onError: (err) => { console.error(err); }
});

// Publish
await topicClient.publish('websocket', 'mychannel', JSON.stringify({ detail }));

Momento公式SDKの中にサンプルがあったので、動作確認しながらMomento Topicsを試してみます。

ソース元

以下にMomentoのJavaScript用のSDKが公開されており、こちらのコードの一部を試しに使っていきます。SDKの実装自体はTypeScriptで書かれています。

https://github.com/momentohq/client-sdk-javascript/tree/main

関連箇所

全体の構成としては、MomentoのAPIキーから一時的な認証情報(ここからは公式サイトを真似てMomento Tokenと呼びます)を生成するためのトークン生成器と実際に生成したMomento Tokenを使用するサンプルWebアプリ(Vite)に分かれています。

使ってみた

早速サンプルを試してみます。まずはViteをベースにしたサンプルのReadmeを読むとトークン生成器の準備が必要と書かれています。なので、先にトークン生成器でMomento Tokenを生成できるよう準備します。

token-vending-machineの作成

https://github.com/momentohq/client-sdk-javascript/tree/main/examples/nodejs/token-vending-machine

上記のリソースをAWS環境にデプロイするため、事前にMomentoのコンソールにログインしAPIキーを生成します。生成する流れは以下の資料のp.69~p.76辺りをみると確認できます。

https://speakerdeck.com/yushikatoaws/momentogakao-erukai-fa-zhe-nowei-lai-qian-ban?slide=69

手順にはないですが、サンプルが特定のCacheを使うことが前提となっているので、このまま実行すると権限不足になります。なので、以下のコードを変更し生成するMomento Tokenの権限を広げます。(本番では使用するCacheのみに設定したほうがよいです)

https://github.com/momentohq/client-sdk-javascript/blob/90f8e789e8fe83ea8ac3123609ca25b53ce2dd9d/examples/nodejs/token-vending-machine/lambda/token-vending-machine/config.ts#L42-L54

DisposableTokenScopeを以下のように変更します。

export const tokenPermissions: DisposableTokenScope = {
  permissions: [
    {
      role: CacheRole.ReadWrite,
      cache: AllCaches,  //←元ソース cache: 'default-cache',
    },
    {
      role: TopicRole.PublishSubscribe,
      cache: AllCaches,  //←元ソース cache: 'default-cache',
      topic: AllTopics,
    },
  ],
};

Readmeに従って、MomentoApiKeyパラメータに取得したMomento APIキーをセッティングしてCDKからリソースをデプロイします。一点注意として、Docker上でのビルドが実行されるのでDocker DesktopやRancher Desktopなどを事前に起動してください。

git clone https://github.com/momentohq/client-sdk-javascript.git
cd examples/nodejs/token-vending-machine/infrastructure
npm install

npm run deploy -- --parameters MomentoApiKey=<YOUR_MOMENTO_API_KEY>

デプロイすると以下のようなAWSリソースが展開されます。ターミナルやブラウザなどからAPI GatewayのエンドポイントにアクセスするとMomento Tokenが取得できます。

momento-token-vending-machine-arch.jpg

curlでMomento Tokenが取得できるか確認できます。

% curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/
{"authToken":"eyJXXXXXXXXXXXX","expiresAt":1727518127}%

デフォルトだとOpen設定で誰でもトークン取得可能ですが、Configを切り替えることでLambdaAuthorizerやAmazonCognitoを使う方式にも切り替えられます。詳細は以下の部分を確認してください。

https://github.com/momentohq/client-sdk-javascript/blob/90f8e789e8fe83ea8ac3123609ca25b53ce2dd9d/examples/nodejs/token-vending-machine/lambda/token-vending-machine/config.ts#L72-L77

サンプルアプリの実行(Vite)

ここから使用するMomento Topicの作成と、サンプルアプリのデプロイを実施します。まずはMomento Cacheの作成です。Momento Consoleから以下のように画面に沿ってCacheを作成します。

01-momento-top.png

02-momento-cache.png

03-momento-create-cache.png

作成できたら次はサンプルアプリを実行します。

https://github.com/momentohq/client-sdk-javascript/tree/main/examples/web/vite-chat-app

実行は非常に単純で、Config用のファイルがあるので先ほどデプロイしたAPI Gatewayのエンドポイントを設定し、使用するMomento Cacheの名前を設定しローカルで実行することで使用できます。VITE_TOKEN_VENDING_MACHINE_AUTH_TYPEはトークン生成器に合わせてlambda,cognitoも設定出来ます。

examples/web/vite-chat-app/.env.development
VITE_TOKEN_VENDING_MACHINE_URL="<デプロイしたAPI GatewayのURL>"
VITE_MOMENTO_CACHE_NAME="<momentoに設定したcacheの名前>"
VITE_TOKEN_VENDING_MACHINE_AUTH_TYPE="open"  

上記が設定できたら以下でローカル実行できます。

cd -
cd examples/web/vite-chat-app
npm install
npm run dev

上記デプロイができるとhttp://localhost:5173でアプリに接続できます。アプリを2つ開くと以下のように、Momento Topicを経由してWebSocketが実現出来ることが分かります。左側がtest1ユーザで、右側がtest2ユーザです。
ただ、なぜか重複してデータが表示されるので描画の際は冪等な処理が必要そうです。

momento-topic-demo.gif

サンプルコードを見ると、SDK経由でpublish/subscribeするだけでWebSocketが実現できています。今後以下のコード部分をベースに、別途IoTに関連するサンプルを作って詳細を確認してみます。

https://github.com/momentohq/client-sdk-javascript/blob/main/examples/web/vite-chat-app/src/utils/momento-web.ts

所感

他にもWebSocketのサービスはありそうですが、バックエンドの実装をほぼMomento Topics側にお願いできるのでかなり有用に感じました!気になる方はぜひ一緒にサンプル試してみてください!

参考

https://www.gomomento.com/blog/why-are-websockets-so-hard/

https://jp.gomomento.com/blog/how-we-built-momento-topics-a-serverless-websocket-service/

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.